wayland: fall back to shm_open if memfd unavailable
authorRay Strode <rstrode@redhat.com>
Thu, 12 May 2016 19:52:12 +0000 (15:52 -0400)
committerRay Strode <rstrode@redhat.com>
Thu, 16 Jun 2016 16:02:51 +0000 (12:02 -0400)
Debian stable currently ships with a 3.16 kernel, so
it doesn't have memfd available.

This commit adds shm_open fall back code for that case
(for now).

https://bugzilla.gnome.org/show_bug.cgi?id=766341

configure.ac
gdk/wayland/gdkdisplay-wayland.c

index 0b0b61beccc4efbb7ed3de80f7e92401b3de41b6..0502f3351279c1bc4c0d9141f2c51d67c2c28036 100644 (file)
@@ -810,6 +810,9 @@ LIBS="$LIBS $GLIB_LIBS"
 AC_CHECK_FUNCS(bind_textdomain_codeset)
 LIBS=$gtk_save_LIBS
 
+AC_CHECK_HEADERS(linux/memfd.h,
+                 AC_DEFINE(HAVE_LINUX_MEMFD_H, 1,
+                           [Define to 1 if memfd.h is available]))
 AC_CHECK_HEADERS(sys/mman.h,
                  AC_DEFINE(HAVE_SYS_MMAN_H, 1,
                            [Define to 1 if mman.h is available]))
index 9f78f298028443ab6b07907256ddee575517330c..d8b71b79998e19b9aad9ab66350d3ac9a336cd51 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
+
+#ifdef HAVE_LINUX_MEMFD_H
 #include <linux/memfd.h>
+#endif
+
 #include <sys/mman.h>
 #include <sys/syscall.h>
 
@@ -1107,16 +1111,47 @@ typedef struct _GdkWaylandCairoSurfaceData {
 static int
 open_shared_memory (void)
 {
-  int ret;
+  static gboolean force_shm_open = FALSE;
+  int ret = -1;
+
+#if !defined (__NR_memfd_create)
+  force_shm_open = TRUE;
+#endif
 
   do
     {
-      ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);
+#if defined (__NR_memfd_create)
+      if (!force_shm_open)
+        {
+          ret = syscall (__NR_memfd_create, "gdk-wayland", MFD_CLOEXEC);
+
+          /* fall back to shm_open until debian stops shipping 3.16 kernel
+           * See bug 766341
+           */
+          if (ret < 0 && errno == ENOSYS)
+            force_shm_open = TRUE;
+        }
+#endif
+
+      if (force_shm_open)
+        {
+          char name[NAME_MAX - 1] = "";
+
+          sprintf (name, "/gdk-wayland-%x", g_random_int ());
+
+          ret = shm_open (name, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0600);
+
+          if (ret >= 0)
+            shm_unlink (name);
+          else if (errno == EEXIST)
+            continue;
+        }
     }
   while (ret < 0 && errno == EINTR);
 
   if (ret < 0)
-    g_critical (G_STRLOC ": creating shared memory file failed: %m");
+    g_critical (G_STRLOC ": creating shared memory file (using %s) failed: %m",
+                force_shm_open? "shm_open" : "memfd_create");
 
   return ret;
 }